/**
 * 音频工具类 - 专门处理HBuilderX APP中的音频加载问题
 */

// 环境检测
export const isHBuilderXApp = () => {
  // console.log("这是isHBuilderXApp")
  // 检测是否在HBuilderX打包的APP环境中
  return window.navigator.userAgent.includes('HBuilder') || 
         window.navigator.userAgent.includes('uni-app') ||
         window.navigator.userAgent.includes('DCloud') ||
         typeof window.plus !== 'undefined'
}

// 检测是否支持Web Audio API
export const isWebAudioSupported = () => {
  return typeof window.AudioContext !== 'undefined' || 
         typeof window.webkitAudioContext !== 'undefined'
}

// 检测是否支持fetch API
export const isFetchSupported = () => {
  return typeof window.fetch !== 'undefined'
}

// 获取音频文件名映射
export const getAudioFileName = (soundType) => {
  const fileNameMap = {
    'kanong': 'kanong.mp3',
    'in_love_with_a_ghost': 'In Love With a Ghost-We\'ve Never Met but Can We Have a Cup of Coffee or Somethin.mp3',
    'loveless': 'Loveless (Inst.).mp3',
    'clear_as_day': 'Thomas Greenberg-Clear as Day.mp3',
    'save_me': 'Shayne Ward-Save Me.mp3',
    'listen': 'Said The Sky-Listen.mp3',
    'liubian': 'daihaojiu.mp3',
    'qq_tone': 'qqtsy.mp3'
  }
  return fileNameMap[soundType] || ''
}

// 获取所有可能的音频路径（用于重试）
export const getAllAudioPaths = (soundType) => {
  const fileName = getAudioFileName(soundType)
  
  if (isHBuilderXApp()) {
    return [
      // HBuilderX APP 环境下的路径策略
      `./Tones/${fileName}`,
      `../Tones/${fileName}`,
      `../../Tones/${fileName}`,
      `Tones/${fileName}`,
      `/Tones/${fileName}`,
      `./src/Tones/${fileName}`,
      `../src/Tones/${fileName}`,
      `./public/Tones/${fileName}`,
      `../public/Tones/${fileName}`,
      // 尝试不带扩展名的路径
      `./Tones/${fileName.replace('.mp3', '')}`,
      `Tones/${fileName.replace('.mp3', '')}`,
      // 尝试使用base64编码的路径（如果文件较小）
      `data:audio/mp3;base64,${fileName}`
    ]
  }
  
  // 普通浏览器环境
  return [`/Tones/${fileName}`]
}

// 音频加载器类
export class AudioLoader {
  constructor() {
    this.audioContext = null
    this.audioBuffers = new Map()
    this.loadingPromises = new Map() // 防止重复加载
  }

  // 初始化音频上下文
  initAudioContext() {
    if (!this.audioContext) {
      try {
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
        // console.log('音频上下文初始化成功')
      } catch (error) {
        // console.error('初始化音频上下文失败:', error)
        return false
      }
    }
    return true
  }

  // 预加载音频文件
  async preloadAudio(soundType) {
    if (soundType === 'none' || this.audioBuffers.has(soundType)) {
      return this.audioBuffers.get(soundType)
    }

    // 防止重复加载
    if (this.loadingPromises.has(soundType)) {
      return this.loadingPromises.get(soundType)
    }

    const loadPromise = this._doPreloadAudio(soundType)
    this.loadingPromises.set(soundType, loadPromise)
    
    try {
      const result = await loadPromise
      return result
    } finally {
      this.loadingPromises.delete(soundType)
    }
  }

  // 实际执行预加载
  async _doPreloadAudio(soundType) {
    try {
      // console.log(`开始预加载音频文件: ${soundType}`)
      
      // 获取所有可能的路径
      const allPaths = getAllAudioPaths(soundType)
      
      // 根据环境选择优先加载方式
      if (isHBuilderXApp()) {
        // App环境（5+ App）时优先使用HTML5 Audio加载
        // console.log('检测到App环境，优先使用HTML5 Audio加载')
        const html5Result = await this._tryHTML5Audio(soundType, allPaths)
        if (html5Result) {
          // console.log("HTML5 Audio加载成功")
          return html5Result
        }
        
        // 备用方法：使用Web Audio API
        if (isWebAudioSupported() && isFetchSupported()) {
          const webAudioResult = await this._tryWebAudioAPI(soundType, allPaths)
          if (webAudioResult) {
            // console.log("Web Audio API加载成功")
            return webAudioResult
          }
        }
      } else {
        // 其他环境优先使用Web Audio API加载
        // console.log('检测到普通浏览器环境，优先使用Web Audio API加载')
        if (isWebAudioSupported() && isFetchSupported()) {
          const webAudioResult = await this._tryWebAudioAPI(soundType, allPaths)
          if (webAudioResult) {
            // console.log("Web Audio API加载成功")
            return webAudioResult
          }
        }
        
        // 备用方法：使用HTML5 Audio
        const html5Result = await this._tryHTML5Audio(soundType, allPaths)
        if (html5Result) {
          // console.log("HTML5 Audio加载成功")
          return html5Result
        }
      }
      
      throw new Error('所有音频加载方法都失败')
      
    } catch (error) {
      console.error('预加载音频失败:', error)
      // throw error
    }
  }

  // 尝试使用Web Audio API加载
  async _tryWebAudioAPI(soundType, allPaths) {
    for (const audioPath of allPaths) {
      try {
        // console.log(`尝试使用Web Audio API加载: ${audioPath}`)
        const response = await fetch(audioPath)
        if (!response.ok) {
          console.log(`路径 ${audioPath} 加载失败: HTTP ${response.status}`)
          continue
        }
        
        const arrayBuffer = await response.arrayBuffer()
        if (!this.audioContext) {
          this.initAudioContext()
        }
        const audioBuffer = await this.audioContext.decodeAudioData(arrayBuffer)
        this.audioBuffers.set(soundType, audioBuffer)
        
        // console.log(`音频文件 ${soundType} 使用Web Audio API预加载成功，路径: ${audioPath}`)
        return audioBuffer
        
      } catch (error) {
        console.log(`路径 ${audioPath} 加载失败:`, error.message)
        continue
      }
    }
    return null
  }

  // 尝试使用HTML5 Audio加载
  async _tryHTML5Audio(soundType, allPaths) {
    for (const audioPath of allPaths) {
      try {
        // console.log(`尝试备用方法路径: ${audioPath}`)
        
        const audio = new Audio()
        audio.preload = 'auto'
        audio.src = audioPath
        
        // 等待音频加载完成
        await new Promise((resolve, reject) => {
          const timeout = setTimeout(() => {
            reject(new Error('音频加载超时'))
          }, 5000) // 5秒超时
          
          audio.addEventListener('canplaythrough', () => {
            clearTimeout(timeout)
            resolve()
          }, { once: true })
          
          audio.addEventListener('error', (e) => {
            clearTimeout(timeout)
            reject(new Error(`音频加载错误: ${e.target.error?.message || '未知错误'}`))
          }, { once: true })
          
          audio.load()
        })
        
        // 将HTML5 Audio元素存储起来，用于播放
        const audioData = { type: 'html5', audio }
        this.audioBuffers.set(soundType, audioData)
        
        // console.log(`音频文件 ${soundType} 使用备用方法预加载成功，路径: ${audioPath}`)
        return audioData
        
      } catch (error) {
        console.log(`备用方法路径 ${audioPath} 失败:`, error.message)
        continue
      }
    }
    return null
  }

  // 播放音频
  async playAudio(soundType, volume = 1.0, loop = false) {
    try {
      // 确保音频已预加载
      const audioData = await this.preloadAudio(soundType)
      if (!audioData) {
        throw new Error('音频文件未加载')
      }

      if (audioData.type === 'html5') {
        // 使用HTML5 Audio播放
        const audio = audioData.audio
        audio.currentTime = 0
        audio.volume = volume
        audio.loop = loop
        
        await audio.play()
        return { type: 'html5', audio, stop: () => audio.pause() }
        
      } else {
        // 使用Web Audio API播放
        if (!this.audioContext) {
          this.initAudioContext()
        }
        
        const source = this.audioContext.createBufferSource()
        source.buffer = audioData
        source.loop = loop
        
        const gainNode = this.audioContext.createGain()
        gainNode.gain.value = volume
        
        source.connect(gainNode)
        gainNode.connect(this.audioContext.destination)
        
        source.start(0)
        return { type: 'webaudio', source, gainNode, stop: () => source.stop() }
      }
      
    } catch (error) {
      console.error('播放音频失败:', error)
      // throw error
    }
  }

  // 清理资源
  cleanup() {
    // 清空音频缓存
    this.audioBuffers.clear()
    
    // 关闭音频上下文
    if (this.audioContext && this.audioContext.state !== 'closed') {
      try {
        this.audioContext.close()
      } catch (error) {
        console.error('关闭音频上下文失败:', error)
      }
    }
    
    // 清空加载中的Promise
    this.loadingPromises.clear()
  }
}

// 创建全局音频加载器实例
export const audioLoader = new AudioLoader()

// 导出默认实例
export default audioLoader
